home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / MacPNG Library 1.02 / pngMacSrc 1.02 / PNG Library 0.80 / PNGMEM.C < prev    next >
Text File  |  1996-05-29  |  8KB  |  316 lines

  1.  
  2. /* pngstub.c - stub functions for i/o and memory allocation
  3.  
  4.    libpng 1.0 beta 2 - version 0.8
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995 Guy Eric Schalnat, Group 42, Inc.
  7.    August 20, 1995
  8.  
  9.    This file provides a location for all memory allocation.  Users which
  10.    need special memory handling are expected to modify the code in this file
  11.    to meet their needs.  See the instructions at each function. */
  12.  
  13. #define PNG_INTERNAL
  14. #include "png.h"
  15.  
  16. /* Allocate memory.  For reasonable files, size should never exceed
  17.    64K.  However, zlib may allocate more then 64K if you don't tell
  18.    it not to.  See zconf.h and png.h for more information. zlib does
  19.    need to allocate exactly 64K, so whatever you call here must
  20.    have the ability to do that. */
  21.  
  22. /* Borland compilers have this habit of not giving you 64K chunks
  23.    that start on the segment in DOS mode.  This has not been observed
  24.    in Windows, and of course it doesn't matter in 32 bit mode, as there
  25.    are no segments.  Now libpng doesn't need that much memory normally,
  26.    but zlib does, so we have to normalize it, if necessary.  It would be
  27.    better if zlib worked in less then 64K, but it doesn't, so we
  28.    have to deal with it.  Truely, we are misusing farmalloc here,
  29.    as it is designed for use with huge pointers, which don't care
  30.    about segments.  So we allocate a large amount of memory, and
  31.    divvy off segments when needed.
  32.    */
  33. #ifdef __TURBOC__
  34. #ifndef __WIN32__
  35. #ifndef __FLAT__
  36.  
  37. /* NUM_SEG is the number of segments allocated at once */
  38. #define NUM_SEG 4
  39. typedef struct borland_seg_struct
  40. {
  41.    void *mem_ptr;
  42.    void *seg_ptr[NUM_SEG];
  43.    int seg_used[NUM_SEG];
  44.    int num_used;
  45. } borland_seg;
  46.  
  47. borland_seg *save_array;
  48. int num_save_array;
  49. int max_save_array;
  50.  
  51. #endif
  52. #endif
  53. #endif
  54.  
  55. void *
  56. png_large_malloc(png_struct *png_ptr, png_uint_32 size)
  57. {
  58.    void *ret;
  59.  
  60.    if (!png_ptr || !size)
  61.       return ((void *)0);
  62.  
  63. #ifdef PNG_MAX_MALLOC_64K
  64.    if (size > (png_uint_32)65536L)
  65.       png_error(png_ptr, "Cannot Allocate > 64K");
  66. #endif
  67.  
  68. #ifdef __TURBOC__
  69. #  if defined(__WIN32__) || defined(__FLAT__)
  70.    ret = malloc(size);
  71. #  else
  72.  
  73.    if (size == 65536L)
  74.    {
  75.       unsigned long offset;
  76.       if (!save_array)
  77.       {
  78.          ret = farmalloc(size);
  79.          offset = (unsigned long)(ret);
  80.          offset &= 0xffffL;
  81.       }
  82.       else
  83.       {
  84.          ret = (void *)0;
  85.       }
  86.       if (save_array || offset)
  87.       {
  88.          int i, j;
  89.  
  90.          if (ret)
  91.             farfree(ret);
  92.          ret = (void *)0;
  93.  
  94.          if (!save_array)
  95.          {
  96.             unsigned long offset;
  97.             png_byte huge *ptr;
  98.             int i;
  99.  
  100.             num_save_array = 1;
  101.             save_array = malloc(num_save_array * sizeof (borland_seg));
  102.             if (!save_array)
  103.                png_error(png_ptr, "Out of Memory");
  104.             save_array->mem_ptr = farmalloc(
  105.                (unsigned long)(NUM_SEG) * 65536L + 65532L);
  106.             if (!save_array->mem_ptr)
  107.                png_error(png_ptr, "Out of Memory");
  108.             offset = (unsigned long)(ret);
  109.             offset &= 0xffffL;
  110.             ptr = save_array->mem_ptr;
  111.             if (offset)
  112.                ptr += 65536L - offset;
  113.             for (i = 0; i < NUM_SEG; i++, ptr += 65536L)
  114.             {
  115.                save_array->seg_ptr[i] = ptr;
  116.                save_array->seg_used[i] = 0;
  117.             }
  118.             save_array->num_used = 0;
  119.          }
  120.  
  121.          for (i = 0; i < num_save_array; i++)
  122.          {
  123.             for (j = 0; j < NUM_SEG; j++)
  124.             {
  125.                if (!save_array[i].seg_used[j])
  126.                {
  127.                   ret = save_array[i].seg_ptr[j];
  128.                   save_array[i].seg_used[j] = 1;
  129.                   save_array[i].num_used++;
  130.                   break;
  131.                }
  132.             }
  133.             if (ret)
  134.                break;
  135.          }
  136.  
  137.          if (!ret)
  138.          {
  139.             unsigned long offset;
  140.             png_byte huge *ptr;
  141.  
  142.             save_array = realloc(save_array,
  143.                (num_save_array + 1) * sizeof (borland_seg));
  144.             if (!save_array)
  145.                png_error(png_ptr, "Out of Memory");
  146.             save_array[num_save_array].mem_ptr = farmalloc(
  147.                (unsigned long)(NUM_SEG) * 65536L + 65532L);
  148.             if (!save_array[num_save_array].mem_ptr)
  149.                png_error(png_ptr, "Out of Memory");
  150.             offset = (unsigned long)(ret);
  151.             offset &= 0xffffL;
  152.             ptr = save_array[num_save_array].mem_ptr;
  153.             if (offset)
  154.                ptr += 65536L - offset;
  155.             for (i = 0; i < NUM_SEG; i++, ptr += 65536L)
  156.             {
  157.                save_array[num_save_array].seg_ptr[i] = ptr;
  158.                save_array[num_save_array].seg_used[i] = 0;
  159.             }
  160.             ret = save_array[num_save_array].seg_ptr[0];
  161.             save_array[num_save_array].seg_used[0] = 1;
  162.             save_array[num_save_array].num_used = 1;
  163.             num_save_array++;
  164.          }
  165.       }
  166.    }
  167.    else
  168.    {
  169.       ret = farmalloc(size);
  170.    }
  171.  
  172. #  endif /* __WIN32__ */
  173. #else /* __TURBOC__ */
  174. #  ifdef _MSC_VER
  175.    ret = halloc(size, 1);
  176. #  else
  177.    /* everybody else, so normal malloc should do it. */
  178.    ret = malloc(size);
  179. #  endif
  180. #endif
  181.  
  182.    if (!ret)
  183.    {
  184.       png_error(png_ptr, "Out of Memory");
  185.    }
  186.  
  187.    return ret;
  188. }
  189.  
  190. /* free a pointer allocated by png_large_malloc().  In the default
  191.   configuration, png_ptr is not used, but is passed in case it
  192.   is needed.  If ptr is NULL, return without taking any action. */
  193. void
  194. png_large_free(png_struct *png_ptr, void *ptr)
  195. {
  196.    if (!png_ptr)
  197.       return;
  198.  
  199.    if (ptr != (void *)0)
  200.    {
  201. #ifdef __TURBOC__
  202. #  if defined(__WIN32__) || defined(__FLAT__)
  203.       if (ptr)
  204.          free(ptr);
  205. #  else
  206.       int i, j;
  207.  
  208.       for (i = 0; i < num_save_array; i++)
  209.       {
  210.          for (j = 0; j < NUM_SEG; j++)
  211.          {
  212.             if (ptr == save_array[i].seg_ptr[j])
  213.             {
  214.                save_array[i].seg_used[j] = 0;
  215.                ptr = 0;
  216.                save_array[i].num_used--;
  217.                if (!save_array[i].num_used)
  218.                {
  219.                   int k;
  220.  
  221.                   num_save_array--;
  222.                   farfree(save_array[i].mem_ptr);
  223.                   for (k = i; k < num_save_array; k++)
  224.                      save_array[k] = save_array[k + 1];
  225.                   if (!num_save_array)
  226.                   {
  227.                      free(save_array);
  228.                      save_array = 0;
  229.                   }
  230.                }
  231.                break;
  232.             }
  233.          }
  234.          if (!ptr)
  235.             break;
  236.       }
  237.  
  238.       if (ptr)
  239.          farfree(ptr);
  240. #  endif
  241. #else
  242. #  ifdef _MSC_VER
  243.       hfree(ptr);
  244. #  else
  245.       free(ptr);
  246. #  endif
  247. #endif
  248.    }
  249. }
  250.  
  251. /* Allocate memory.  This is called for smallish blocks only  It
  252.    should not get anywhere near 64K. */
  253. void *
  254. png_malloc(png_struct *png_ptr, png_uint_32 size)
  255. {
  256.    void *ret;
  257.  
  258.    if (!png_ptr || !size)
  259.       return ((void *)0);
  260.  
  261. #ifdef PNG_MAX_MALLOC_64K
  262.    if (size > (png_uint_32)65536L)
  263.       png_error(png_ptr, "Cannot Allocate > 64K");
  264. #endif
  265.  
  266.    ret = malloc((png_size_t)size);
  267.  
  268.    if (!ret)
  269.    {
  270.       png_error(png_ptr, "Out of Memory");
  271.    }
  272.  
  273.    return ret;
  274. }
  275.  
  276. /* Reallocate memory.  This will not get near 64K on a
  277.    even marginally reasonable file. */
  278. void *
  279. png_realloc(png_struct *png_ptr, void *ptr, png_uint_32 size,
  280.    png_uint_32 old_size)
  281. {
  282.    void *ret;
  283.  
  284.    if (!png_ptr || !old_size || !ptr || !size)
  285.       return ((void *)0);
  286.  
  287. #ifdef PNG_MAX_MALLOC_64K
  288.    if (size > (png_uint_32)65536L)
  289.       png_error(png_ptr, "Cannot Allocate > 64K");
  290. #endif
  291.  
  292.    ret = realloc(ptr, (png_size_t)size);
  293.  
  294.    if (!ret)
  295.    {
  296.       png_error(png_ptr, "Out of Memory");
  297.    }
  298.  
  299.    return ret;
  300. }
  301.  
  302. /* free a pointer allocated by png_malloc().  In the default
  303.   configuration, png_ptr is not used, but is passed incase it
  304.   is needed.  If ptr is NULL, return without taking any action. */
  305. void
  306. png_free(png_struct *png_ptr, void *ptr)
  307. {
  308.    if (!png_ptr)
  309.       return;
  310.  
  311.    if (ptr != (void *)0)
  312.       free(ptr);
  313. }
  314.  
  315.  
  316.